package com.bawei.lookfor2204a.view.fragment.zhibo

import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import coil.load
import com.ayvytr.adapter.smart
import com.bawei.lookfor2204a.R
import com.bawei.lookfor2204a.base.BaseFragment
import com.bawei.lookfor2204a.databinding.FragmentZhiBoBinding
import com.bawei.lookfor2204a.model.RsaCoder
import com.bawei.lookfor2204a.model.VideoFilterBean
import com.bawei.lookfor2204a.view.activity.realname.RealNameActivity
import com.blankj.utilcode.util.ToastUtils
import com.blankj.utilcode.util.UriUtils
import com.ksyun.media.streamer.capture.CameraCapture
import com.ksyun.media.streamer.filter.imgtex.ImgBeautySpecialEffectsFilter
import com.ksyun.media.streamer.filter.imgtex.ImgTexFilterMgt
import com.ksyun.media.streamer.kit.KSYStreamer
import com.ksyun.media.streamer.kit.StreamerConstants
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File


/**
 * 直播Fragment页面
 */
class ZhiBoFragment : BaseFragment<ZhiBoViewModel, FragmentZhiBoBinding>(R.layout.fragment_zhi_bo) {

    var currentVideoFilter = 1  // 当前是美颜 还是滤镜 1美颜，2滤镜
    val meiYanLvJingAdapter = smart(
        mutableListOf<VideoFilterBean>(),
        R.layout.item_meiyan_lvjing,
        { item, position ->
            findViewById<TextView>(R.id.tv_name).text = item.name
        }
    ) {}.click { item, position ->
        if (currentVideoFilter == 1) {
            // 执行美颜代码
            //设置美颜
            mStreamer.getImgTexFilterMgt().setFilter(
                mStreamer.getGLRender(), item.value
            )
        } else {
            // 创建风格滤镜
            val effectsFilter = ImgBeautySpecialEffectsFilter(
                mStreamer.glRender,
                activity,
                item.value
            )
            // 设置风格滤镜
            mStreamer.imgTexFilterMgt.setFilter(effectsFilter)
        }
    }

    override fun initData() {
        // 申请开直播成功的数据处理
        viewModel.openLiveSuccess.observe(this, {
            ToastUtils.showShort(it.message)
            if (it.liveData != null) {
                // 对RTMP流地址 进行解密 和 加密
                val liveRtmpUrl = it.liveData.liveRtmpUrl
                val split = liveRtmpUrl.split("pwd=")
                val pwd = RsaCoder.encryptByPublicKey(RsaCoder.decryptByPublicKey(split[1]))

                // 开始推流
                mStreamer.url = "${split[0]}pwd=${
                    pwd.replace("/".toRegex(), "-").replace("\\+".toRegex(), "~")
                }"
                mStreamer.startStream()
            }
        })

        // 检测实名认证liveData
        viewModel.checkVerifiedSuccess.observe(this, {
            if (it.result.status) {
                ToastUtils.showShort("你已经完成实名认证了，可以开始直播")
            } else {
                val dialog = AlertDialog.Builder(requireActivity()).create()
                val view =
                    LayoutInflater.from(requireActivity()).inflate(R.layout.dialog_shiming, null)

                // 找到实名认证按钮
                val btnToShiMing = view.findViewById<Button>(R.id.btn_to_shi_ming)
                btnToShiMing.setOnClickListener {
                    // 跳转到实名认证页面
                    startActivity(Intent(requireActivity(), RealNameActivity::class.java))
                }

                dialog.setView(view)
                dialog.show()
            }
        })
    }

    override fun initView() {
        // 检测有没有实名认证，没有实名认证，弹窗让用户实名认证
        viewModel.checkVerified()

        // 初始化金山云 推流
        initStream()

        // 选择封面
        binding.ivCover.setOnClickListener {
            startActivityForResult(Intent(Intent.ACTION_PICK).apply {
                type = "image/*"
            }, 1001)
        }

        // 直播类型单选
        binding.rgType.setOnCheckedChangeListener { radioGroup, i ->
            when (i) {
                R.id.rb_type101 -> liveType = 101
                R.id.rb_type102 -> liveType = 102
                R.id.rb_type103 -> liveType = 103
                R.id.rb_type104 -> liveType = 104
            }
        }

        // 开播
        binding.btnOpenLive.setOnClickListener {
            val body = RequestBody.create("multipart/form-data".toMediaTypeOrNull(), file)
            val part = MultipartBody.Part.createFormData("liveCoverImage", file.name, body)
            viewModel.openLive(
                liveType,
                binding.etTitle.text.toString(),
                "110",
                "110",
                part
            )
        }

        // 下播
        binding.btnCloseLive.setOnClickListener {
            ToastUtils.showShort("下播成功！")
            mStreamer.stopStream()
        }

        // 美颜
        binding.btnMeiYan.setOnClickListener {
            //设置美颜
            mStreamer.getImgTexFilterMgt().setFilter(
                mStreamer.getGLRender(), ImgTexFilterMgt.KSY_FILTER_BEAUTY_SOFT
            );
        }

        // 美颜滤镜选择列表
        binding.recVideoFilter.layoutManager =
            LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
        binding.recVideoFilter.adapter = meiYanLvJingAdapter
        // 美颜选择
        binding.btnMeiYanXuanZe.setOnClickListener {
            if (binding.recVideoFilter.visibility == View.GONE) {
                binding.recVideoFilter.visibility = View.VISIBLE
                meiYanLvJingAdapter.clear()
                meiYanLvJingAdapter.update(viewModel.meiYanList)
                currentVideoFilter = 1
            } else {
                binding.recVideoFilter.visibility = View.GONE
            }
        }

        // 滤镜选择
        binding.btnLvJingXuanZe.setOnClickListener {
            if (binding.recVideoFilter.visibility == View.GONE) {
                binding.recVideoFilter.visibility = View.VISIBLE
                meiYanLvJingAdapter.clear()
                meiYanLvJingAdapter.update(viewModel.lvJingList)
                currentVideoFilter = 2
            } else {
                binding.recVideoFilter.visibility = View.GONE
            }
        }
    }

    // 直播类型
    var liveType = 101

    // 直播封面照片文件
    lateinit var file: File
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        // 回显封面照片
        file = UriUtils.uri2File(data?.data)
        binding.ivCover.load(file)
    }

    lateinit var mStreamer: KSYStreamer
    private fun initStream() {
        // 创建KSYStreamer实例
        mStreamer = KSYStreamer(activity)
        // 设置预览View
        mStreamer.setDisplayPreview(binding.cameraPreview)
        // 设置推流url（需要向相关人员申请，测试地址并不稳定！）
        mStreamer.setUrl("rtmp://mobile.kscvbu.cn/live/{streamName}")
        // 设置预览分辨率, 当一边为0时，SDK会根据另一边及实际预览View的尺寸进行计算
        mStreamer.setPreviewResolution(480, 0)
        // 设置推流分辨率，可以不同于预览分辨率（不应大于预览分辨率，否则推流会有画质损失）
        mStreamer.setTargetResolution(480, 0)
        // 设置预览帧率
        mStreamer.setPreviewFps(15F)
        // 设置推流帧率，当预览帧率大于推流帧率时，编码模块会自动丢帧以适应设定的推流帧率
        mStreamer.setTargetFps(15F)
        // 设置视频码率，分别为初始平均码率、最高平均码率、最低平均码率，单位为kbps，另有setVideoBitrate接口，单位为bps
        mStreamer.setVideoKBitrate(600, 800, 400)
        // 设置音频采样率
        mStreamer.setAudioSampleRate(44100)
        // 设置音频码率，单位为kbps，另有setAudioBitrate接口，单位为bps
        mStreamer.setAudioKBitrate(48)
        /**
         * 设置编码模式(软编、硬编)，请根据白名单和系统版本来设置软硬编模式，不要全部设成软编或者硬编,白名单可以联系金山云商务:
         * StreamerConstants.ENCODE_METHOD_SOFTWARE
         * StreamerConstants.ENCODE_METHOD_HARDWARE
         */
        mStreamer.setEncodeMethod(StreamerConstants.ENCODE_METHOD_SOFTWARE)
        // 设置屏幕的旋转角度，支持 0, 90, 180, 270
        mStreamer.setRotateDegrees(0)
        // 设置开始预览使用前置还是后置摄像头
        mStreamer.setCameraFacing(CameraCapture.FACING_FRONT)
    }

    override fun getViewModel() = ZhiBoViewModel::class.java

    override fun onResume() {
        super.onResume()
        // 一般可以在onResume中开启摄像头预览
        mStreamer.startCameraPreview()
        // 调用KSYStreamer的onResume接口
        mStreamer.onResume()
        // 如果onPause中切到了DummyAudio模块，可以在此恢复
        mStreamer.setUseDummyAudioCapture(false)
    }

    override fun onPause() {
        super.onPause()
        mStreamer.onPause()
        // 一般在这里停止摄像头采集
        mStreamer.stopCameraPreview()
        // 如果希望App切后台后，停止录制主播端的声音，可以在此切换为DummyAudio采集，
        // 该模块会代替mic采集模块产生静音数据，同时释放占用的mic资源
        mStreamer.setUseDummyAudioCapture(true)
    }

    override fun onDestroy() {
        super.onDestroy()
        // 清理相关资源
        mStreamer.release()
    }
}